﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using UricaoWeb.Datos.Excepciones.Tours;
using UricaoWeb.Datos.ConexionBD.Tours;
using UricaoWeb.Datos.ConexionBD.Propiedad;

namespace UricaoWeb.LogicaDeNegocios.Tours
{
    public class TourLogica
    {
        private OperacionesTour _modelo = new OperacionesTour();


        #region Metodos privados
        /// <summary>
        /// Método que toma un texto para verificar su tamano,
        /// si sobre pasa el límite, se recorta para su impresion
        /// </summary>
        /// <param name="frase">Texto a verificar</param>
        /// <returns>
        /// Retorna el texto simplificado si es el caso, 
        /// en caso contrario, devuelve la misma frase
        /// </returns>
        private string VerificarTamanoTexto(string frase)
        {
            string resultado = "";
            int cantidadCaracteres = 100;

            if (frase.Length > cantidadCaracteres)
            {
                resultado = frase.Substring(0, cantidadCaracteres) + "... ";
                System.Console.WriteLine(resultado);
            }
            else
            {
                resultado = frase;
            }
            return resultado;
        }


        /// <summary>
        /// Método para validar formato de vista del objeto
        /// </summary>
        /// <param name="lista">Lista a recorrer</param>
        /// <returns>
        /// Lista con sus respectivas validaciones
        /// (En este caso, se valida el tamano del texto de la descripcion)
        /// </returns>
        private List<Tour> ValidarLista(List<Tour> lista)
        {
            if (lista != null) 
            {
                foreach (Tour tour in lista)
                {
                    //Verifico el tamnano de la descripción para que no desborde en la pantalla
                    tour.DescripcionTour = VerificarTamanoTexto(tour.DescripcionTour);
                }
            }
            return lista;
        }


        /// <summary>
        /// Método de conversión de una cadena 
        /// en formato HH:MM AM/PM de 12H 
        /// a conversión de 24H (Hora militar)
        /// </summary>
        /// <param name="tiempo">Cadena a procesar</param>
        /// <returns>Cadena procesada </returns>
        private string Conversion24h( string tiempo )
        {
            string nuevoString = "";
            char separador = ':';
            string horaPreDefinido = "00:00";
            
            if (tiempo != "")
            {
                //06:00 PM => split[0] = 06:00, split[1] = PM
                int hora;
                string[] split = tiempo.Split(new Char[] { ' ', });
                
                //06:00  => Horario[0] = 06, Horario[1] = 00;
                string[] horario = split[0].Split(new Char[] { separador, });
                bool parseHora = Int32.TryParse(horario[0], out hora);

                if (!parseHora)
                    Console.WriteLine("Int32.TryParse no pudo realizar la conversion '{0}' a entero (int).\n", hora);
                else
                {
                    if (hora != 12)
                    {
                        if (split[1] == "PM")
                        {
                            hora = hora + 12;
                            nuevoString = hora.ToString() + separador + horario[1];
                        }
                    }
                    if (nuevoString == "")
                    {
                        //Si la hora es 12 PM, 12 AM, Cualquier hora AM
                        nuevoString = split[0];
                    }
                }
            }
            
            if (nuevoString == "") 
            {
                nuevoString = horaPreDefinido;  //Caso borde si no se ha efectuado es casteo
            }
            return nuevoString;
        }

        #endregion

        #region Metodos publicos

        #region Consultas

        /// <summary>
        /// Consulta de todos los tours 
        /// </summary>
        /// <returns></returns>
        public List<Tour> ConsultarTours(int idHotel)
        {
            List<Tour> listaTours = new List<Tour>();
            listaTours = _modelo.ConsultarTours(idHotel);
            listaTours = ValidarLista(listaTours);

            return listaTours;
        }


        /// <summary>
        /// Consulta de todos los tours 
        /// </summary>
        /// <param name="idTour">Id del tour</param>
        /// <returns>Tour deseado</returns>
        public List<Tour> ConsultarTour(int idTour)
        {
            List<Tour> listaTour = new List<Tour>();
            listaTour = _modelo.ConsultarTour(idTour);
            //listaTour = ValidarLista(listaTour);

            return listaTour;
        }


        /// <summary>
        /// Buscador por parametros
        /// </summary>
        /// <param name="parametro">Parametro</param>
        /// <param name="idHote">Tours del hotel</param>
        /// <returns>Retorna la lista de tours deseados</returns>
        public List<Tour> BusquedaTours(string parametro, int idHotel)
        {
            List<Tour> listaTours = new List<Tour>();
            listaTours = _modelo.BusquedaTours(parametro, idHotel);
            listaTours = ValidarLista(listaTours);

            return listaTours;
        }


        /// <summary>
        /// Busca el itinerario de un tour
        /// </summary>
        /// <param name="idTour">Tour deseado</param>
        /// <returns>Lista de listas de string de dos posiciones
        /// donde la primera posicion indica la lista de dias
        /// en que se celebra el tour 
        /// y la segundo indica la hora de inicio y fin del tpur</returns>
        public List<List<string>> ConsultarHorario(int idTour)
        {
            List<List<string>> itinerario = new List<List<string>>();
            List<Horario> resultado = _modelo.ConsultarHorario(idTour);
            List<string> dias = new List<string>();
            List<string> horas = new List<string>();

            try
            {
                foreach (Horario item in resultado)
                {
                    dias.Add(item.Dia);
                }

                string inicio = Conversion24h(resultado[0].HoraInicio);
                string fin = Conversion24h(resultado[0].HoraFin);

                horas.Add(inicio);
                horas.Add(fin);

                itinerario.Add(dias);
                itinerario.Add(horas);
            }
            catch (ArgumentOutOfRangeException e)
            {
                throw new ExcepcionesTours("Índice no válido o negativo", e);
                Console.WriteLine("Disculpe, no se ha podido realizar la petición ", e.Message);
            }
            catch (IndexOutOfRangeException e)
            {
                throw new ExcepcionesTours("Índice fuera del rango o negativo", e);
                Console.WriteLine("Disculpe, no se ha podido realizar la petición ", e.Message);
            }
            catch (Exception e) 
            { 
                throw new ExcepcionesTours("Falla", e); 
                Console.WriteLine("Intente más tarde ", e.Message);
            }

            return itinerario;
        }


        /// <summary>
        /// Consulta de todos los Hoteles 
        /// </summary>
        /// <returns></returns>
        public List<Hotel> ConsultarHoteles()
        {
            List<Hotel> listaHoteles = new List<Hotel>();
            try
            { 
                listaHoteles = _modelo.ConsultarHoteles();
            }
            catch (Exception e)
            {
                Console.Out.Write(e.Message);
            }

            return listaHoteles;
        }


        #endregion


        /// <summary>
        /// Método de llamada a la agregación del tour
        /// </summary>
        /// <param name="nombre">Nombre del tour</param>
        /// <param name="descripcion">Descripcion del tour</param>
        /// <param name="listaDia">Dias de celebración del tour</param>
        /// <param name="horainicio">Hora de inicio del tour</param>
        /// <param name="horafin">Hora final del tour</param>
        /// <param name="capacidad">Capacidad del tour</param>
        /// <param name="precio">Preco actual del tour</param>
        /// <param name="idHotel">Referencia del hotel que ofrece el tour</param>
        /// <returns>Retorna el id del tour agegado</returns>
        public int TourAgregar(string nombre, string descripcion, List<String> listaDia, 
                                string horainicio, string horafin, string capacidad, 
                                string precio, int idHotel)
        {

            int capacidadpersonas = Convert.ToInt32(capacidad);
            int preciotour = Convert.ToInt32(precio);

            int idAgregado = _modelo.TourAgregar(nombre, descripcion, listaDia, 
                                                horainicio, horafin, capacidadpersonas, preciotour, idHotel);

            return idAgregado;
        }



        /// <summary>
        /// Modificar Tours
        /// </summary>
        /// <returns>
        /// Retorna un booleano que indica la ejecución exitoso 
        /// o no de la transacción
        /// </returns>
        public bool ModificarTour(int idTour, string nombre, string descripcion, List<String> listaDia, 
                                    string horainicio, string horafin, string capacidad, string precio, bool activo)
        {
            bool peticion = false;
            try
            {
                int tourActivo = 0; //false
                if (activo)
                    tourActivo = 1; //true

                int capacidadpersonas = Convert.ToInt32(capacidad);
                int preciotour = Convert.ToInt32(precio);
                peticion = _modelo.ModificarTour(idTour, nombre, descripcion, listaDia, horainicio, horafin, capacidadpersonas, preciotour, tourActivo);
                
            }
            catch(Exception e)
            {
                Console.WriteLine("Disculpe, no se ha podido realizar la petición ", e.Message);
            }

            return peticion;
        }



        #endregion
    }
}